{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ITQSdBzjHqZo"
      },
      "source": [
        "# Improving Embeddings with Biased Random Walks in Node2Vec"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "!pip install -q node2vec==0.4.6\n",
        "!pip install -qI gensim==4.3.0"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 983
        },
        "id": "mh8CcD92oFPB",
        "outputId": "c595cf3f-5fbc-4f41-ef47-62ee8f63eb65"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "d:\\Programs\\Anaconda\\envs\\book\\lib\\site-packages\\networkx\\drawing\\nx_pylab.py:433: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored\n",
            "  node_collection = ax.scatter(\n"
          ]
        },
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import networkx as nx\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# Create graph\n",
        "G = nx.erdos_renyi_graph(10, 0.3, seed=1, directed=False)\n",
        "\n",
        "# Plot graph\n",
        "plt.figure()\n",
        "plt.axis('off')\n",
        "nx.draw_networkx(G,\n",
        "                 pos=nx.spring_layout(G, seed=0),\n",
        "                 node_size=600,\n",
        "                 cmap='coolwarm',\n",
        "                 font_size=14,\n",
        "                 font_color='white'\n",
        "                 )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "8SLH3SoHG8zV"
      },
      "outputs": [],
      "source": [
        "import random\n",
        "random.seed(0)\n",
        "import numpy as np\n",
        "np.random.seed(0)\n",
        "\n",
        "def next_node(previous, current, p, q):\n",
        "    alphas = []\n",
        "\n",
        "    # Get the neighboring nodes\n",
        "    neighbors = list(G.neighbors(current))\n",
        "    \n",
        "    # Calculate the appropriate alpha value for each neighbor\n",
        "    for neighbor in neighbors:\n",
        "        # Distance = 0: probability to return to the previous node\n",
        "        if neighbor == previous:\n",
        "            alpha = 1/p\n",
        "        # Distance = 1: probability of visiting a local node\n",
        "        elif G.has_edge(neighbor, previous):\n",
        "            alpha = 1\n",
        "        # Distance = 2: probability to explore an unknown node\n",
        "        else:\n",
        "            alpha = 1/q\n",
        "        alphas.append(alpha)\n",
        "\n",
        "    # Normalize the alpha values to create transition probabilities\n",
        "    probs = [alpha / sum(alphas) for alpha in alphas]\n",
        "    \n",
        "    # Randomly select the new node based on the transition probabilities\n",
        "    next = np.random.choice(neighbors, size=1, p=probs)[0]\n",
        "    return next"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "RWOSysh41bBi"
      },
      "outputs": [],
      "source": [
        "def random_walk(start, length, p, q):\n",
        "    walk = [start]\n",
        "    \n",
        "    for i in range(length):\n",
        "        current = walk[-1]\n",
        "        previous = walk[-2] if len(walk) > 1 else None\n",
        "        next = next_node(previous, current, p, q)\n",
        "        walk.append(next)\n",
        "    \n",
        "    return walk"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "oHhdyOU6yJvj",
        "outputId": "af0a470a-2d77-47e7-e47d-05b7d02a3cb1"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[0, 4, 7, 6, 4, 5, 4, 5, 6]"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "random_walk(0, 8, p=1, q=1)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "iVQx-eHZ6489",
        "outputId": "37163596-7dc9-4f2e-a457-b041f78bf301"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[0, 9, 1, 9, 1, 9, 1, 0, 1]"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "random_walk(0, 8, p=1, q=10)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "X7gTKpm-7HvY",
        "outputId": "ca96cf0a-cb8d-4094-c9a4-90681a36e1c8"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[0, 1, 9, 4, 7, 8, 7, 4, 6]"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "random_walk(0, 8, p=10, q=1)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "YwdzUchynGji",
        "outputId": "dd6b8df6-e3ba-4bdb-eb20-ede3428e017a"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Node2Vec accuracy = 95.45%\n"
          ]
        }
      ],
      "source": [
        "from gensim.models.word2vec import Word2Vec\n",
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn.metrics import accuracy_score\n",
        "\n",
        "# Load dataset\n",
        "G = nx.karate_club_graph()\n",
        "\n",
        "# Process labels (Mr. Hi = 0, Officer = 1)\n",
        "labels = []\n",
        "for node in G.nodes:\n",
        "    label = G.nodes[node]['club']\n",
        "    labels.append(1 if label == 'Officer' else 0)\n",
        "\n",
        "# Create a list of random walks\n",
        "walks = []\n",
        "for node in G.nodes:\n",
        "    for _ in range(80):\n",
        "        walks.append(random_walk(node, 10, 3, 2))\n",
        "\n",
        "# Create and train Word2Vec for DeepWalk\n",
        "node2vec = Word2Vec(walks,\n",
        "                hs=1,   # Hierarchical softmax\n",
        "                sg=1,   # Skip-gram\n",
        "                vector_size=100,\n",
        "                window=10,\n",
        "                workers=2,\n",
        "                min_count=1,\n",
        "                seed=0)\n",
        "node2vec.train(walks, total_examples=node2vec.corpus_count, epochs=30, report_delay=1)\n",
        "\n",
        "# Create masks to train and test the model\n",
        "train_mask = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]\n",
        "test_mask = [0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n",
        "labels = np.array(labels)\n",
        "\n",
        "# Train Node2Vec classifier\n",
        "clf = RandomForestClassifier(random_state=0)\n",
        "clf.fit(node2vec.wv[train_mask], labels[train_mask])\n",
        "\n",
        "# Evaluate accuracy\n",
        "y_pred = clf.predict(node2vec.wv[test_mask])\n",
        "acc = accuracy_score(y_pred, labels[test_mask])\n",
        "print(f'Node2Vec accuracy = {acc*100:.2f}%')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "BH_kxHi3n6-c",
        "outputId": "df83bf1a-30c9-4eee-b522-e6c2d056b523"
      },
      "outputs": [],
      "source": [
        "from io import BytesIO\n",
        "from urllib.request import urlopen\n",
        "from zipfile import ZipFile\n",
        "\n",
        "url = 'https://files.grouplens.org/datasets/movielens/ml-100k.zip'\n",
        "with urlopen(url) as zurl:\n",
        "    with ZipFile(BytesIO(zurl.read())) as zfile:\n",
        "        zfile.extractall('.')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 424
        },
        "id": "ECKHNh1opdhO",
        "outputId": "1e38d425-7297-47ec-9f6f-6d06c142fd14"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>user_id</th>\n",
              "      <th>movie_id</th>\n",
              "      <th>rating</th>\n",
              "      <th>unix_timestamp</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>196</td>\n",
              "      <td>242</td>\n",
              "      <td>3</td>\n",
              "      <td>881250949</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>186</td>\n",
              "      <td>302</td>\n",
              "      <td>3</td>\n",
              "      <td>891717742</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>22</td>\n",
              "      <td>377</td>\n",
              "      <td>1</td>\n",
              "      <td>878887116</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>244</td>\n",
              "      <td>51</td>\n",
              "      <td>2</td>\n",
              "      <td>880606923</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>166</td>\n",
              "      <td>346</td>\n",
              "      <td>1</td>\n",
              "      <td>886397596</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99995</th>\n",
              "      <td>880</td>\n",
              "      <td>476</td>\n",
              "      <td>3</td>\n",
              "      <td>880175444</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99996</th>\n",
              "      <td>716</td>\n",
              "      <td>204</td>\n",
              "      <td>5</td>\n",
              "      <td>879795543</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99997</th>\n",
              "      <td>276</td>\n",
              "      <td>1090</td>\n",
              "      <td>1</td>\n",
              "      <td>874795795</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99998</th>\n",
              "      <td>13</td>\n",
              "      <td>225</td>\n",
              "      <td>2</td>\n",
              "      <td>882399156</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99999</th>\n",
              "      <td>12</td>\n",
              "      <td>203</td>\n",
              "      <td>3</td>\n",
              "      <td>879959583</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>100000 rows × 4 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "       user_id  movie_id  rating  unix_timestamp\n",
              "0          196       242       3       881250949\n",
              "1          186       302       3       891717742\n",
              "2           22       377       1       878887116\n",
              "3          244        51       2       880606923\n",
              "4          166       346       1       886397596\n",
              "...        ...       ...     ...             ...\n",
              "99995      880       476       3       880175444\n",
              "99996      716       204       5       879795543\n",
              "99997      276      1090       1       874795795\n",
              "99998       13       225       2       882399156\n",
              "99999       12       203       3       879959583\n",
              "\n",
              "[100000 rows x 4 columns]"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import pandas as pd\n",
        "\n",
        "ratings = pd.read_csv('ml-100k/u.data', sep='\\t', names=['user_id', 'movie_id', 'rating', 'unix_timestamp'])\n",
        "ratings"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 424
        },
        "id": "8MVzt96-zX5w",
        "outputId": "2479d79e-dfd8-4373-f3e4-fb9be7b56d90"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>movie_id</th>\n",
              "      <th>title</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>1</td>\n",
              "      <td>Toy Story (1995)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>2</td>\n",
              "      <td>GoldenEye (1995)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>3</td>\n",
              "      <td>Four Rooms (1995)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>4</td>\n",
              "      <td>Get Shorty (1995)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>5</td>\n",
              "      <td>Copycat (1995)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1677</th>\n",
              "      <td>1678</td>\n",
              "      <td>Mat' i syn (1997)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1678</th>\n",
              "      <td>1679</td>\n",
              "      <td>B. Monkey (1998)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1679</th>\n",
              "      <td>1680</td>\n",
              "      <td>Sliding Doors (1998)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1680</th>\n",
              "      <td>1681</td>\n",
              "      <td>You So Crazy (1994)</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1681</th>\n",
              "      <td>1682</td>\n",
              "      <td>Scream of Stone (Schrei aus Stein) (1991)</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>1682 rows × 2 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "      movie_id                                      title\n",
              "0            1                           Toy Story (1995)\n",
              "1            2                           GoldenEye (1995)\n",
              "2            3                          Four Rooms (1995)\n",
              "3            4                          Get Shorty (1995)\n",
              "4            5                             Copycat (1995)\n",
              "...        ...                                        ...\n",
              "1677      1678                          Mat' i syn (1997)\n",
              "1678      1679                           B. Monkey (1998)\n",
              "1679      1680                       Sliding Doors (1998)\n",
              "1680      1681                        You So Crazy (1994)\n",
              "1681      1682  Scream of Stone (Schrei aus Stein) (1991)\n",
              "\n",
              "[1682 rows x 2 columns]"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "movies = pd.read_csv('ml-100k/u.item', sep='|', usecols=range(2), names=['movie_id', 'title'], encoding='latin-1')\n",
        "movies"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 424
        },
        "id": "QWUWEx_8zpNX",
        "outputId": "0b8e88af-3b1c-482d-9715-d32e8dd7ac63"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>user_id</th>\n",
              "      <th>movie_id</th>\n",
              "      <th>rating</th>\n",
              "      <th>unix_timestamp</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>298</td>\n",
              "      <td>474</td>\n",
              "      <td>4</td>\n",
              "      <td>884182806</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>7</th>\n",
              "      <td>253</td>\n",
              "      <td>465</td>\n",
              "      <td>5</td>\n",
              "      <td>891628467</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>11</th>\n",
              "      <td>286</td>\n",
              "      <td>1014</td>\n",
              "      <td>5</td>\n",
              "      <td>879781125</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>12</th>\n",
              "      <td>200</td>\n",
              "      <td>222</td>\n",
              "      <td>5</td>\n",
              "      <td>876042340</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>16</th>\n",
              "      <td>122</td>\n",
              "      <td>387</td>\n",
              "      <td>5</td>\n",
              "      <td>879270459</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99988</th>\n",
              "      <td>421</td>\n",
              "      <td>498</td>\n",
              "      <td>4</td>\n",
              "      <td>892241344</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99989</th>\n",
              "      <td>495</td>\n",
              "      <td>1091</td>\n",
              "      <td>4</td>\n",
              "      <td>888637503</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99990</th>\n",
              "      <td>806</td>\n",
              "      <td>421</td>\n",
              "      <td>4</td>\n",
              "      <td>882388897</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99991</th>\n",
              "      <td>676</td>\n",
              "      <td>538</td>\n",
              "      <td>4</td>\n",
              "      <td>892685437</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>99996</th>\n",
              "      <td>716</td>\n",
              "      <td>204</td>\n",
              "      <td>5</td>\n",
              "      <td>879795543</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>55375 rows × 4 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "       user_id  movie_id  rating  unix_timestamp\n",
              "5          298       474       4       884182806\n",
              "7          253       465       5       891628467\n",
              "11         286      1014       5       879781125\n",
              "12         200       222       5       876042340\n",
              "16         122       387       5       879270459\n",
              "...        ...       ...     ...             ...\n",
              "99988      421       498       4       892241344\n",
              "99989      495      1091       4       888637503\n",
              "99990      806       421       4       882388897\n",
              "99991      676       538       4       892685437\n",
              "99996      716       204       5       879795543\n",
              "\n",
              "[55375 rows x 4 columns]"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Only consider ratings with the highest score\n",
        "ratings = ratings[ratings.rating >= 4]\n",
        "ratings"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "1IJMriwWpwMO"
      },
      "outputs": [],
      "source": [
        "from collections import defaultdict\n",
        "\n",
        "pairs = defaultdict(int)\n",
        "\n",
        "# Loop through the entire list of users\n",
        "for group in ratings.groupby(\"user_id\"):\n",
        "    # List of IDs of movies rated by the current user\n",
        "    user_movies = list(group[1][\"movie_id\"])\n",
        "\n",
        "    # Count every time two movies are seen together\n",
        "    for i in range(len(user_movies)):\n",
        "        for j in range(i+1, len(user_movies)):\n",
        "            pairs[(user_movies[i], user_movies[j])] += 1"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6Kzw5h3MqGFu",
        "outputId": "b5d3af56-2d5e-4940-edde-4929ac0621bd"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Total number of graph nodes: 410\n",
            "Total number of graph edges: 14936\n"
          ]
        }
      ],
      "source": [
        "# Create a networkx graph\n",
        "G = nx.Graph()\n",
        "\n",
        "# Try to create an edge between movies that are liked together\n",
        "for pair in pairs:\n",
        "    movie1, movie2 = pair\n",
        "    score = pairs[pair]\n",
        "\n",
        "    # The edge is only created when the score is high enough\n",
        "    if score >= 20:\n",
        "        G.add_edge(movie1, movie2, weight=score)\n",
        "\n",
        "print(\"Total number of graph nodes:\", G.number_of_nodes())\n",
        "print(\"Total number of graph edges:\", G.number_of_edges())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 122,
          "referenced_widgets": [
            "eeb0f16e73a44771a4cd98b296a2f504",
            "7cfb833108bb4948bd900d8ea79f6ea7",
            "90e8a5c45e93473d8566096dcda21b00",
            "0214cb6383934ef1856188a9cad2b1f5",
            "e24e7b63096849fc8b290745429a103c",
            "955ac231d4124300bc2c03097a39a256",
            "69a57be4fda84d3aad2c0ecdced02f26",
            "1b84f3c6fa9c4599a59e765f1dda64bc",
            "a2e964b1261743deb4e21d847a85b3bb",
            "bd7eec057b9b463b8ec4a73124d44a90",
            "baf82e035dc745b7bacf4faca185daf1"
          ]
        },
        "id": "O0bB8_0zqe6H",
        "outputId": "b1dd909f-7cec-4a29-cbac-9e666c34692f"
      },
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "2a45951ace0247cca31065e5a3b66c8f",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Computing transition probabilities:   0%|          | 0/410 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Generating walks (CPU: 1): 100%|██████████| 200/200 [00:22<00:00,  8.82it/s]\n"
          ]
        }
      ],
      "source": [
        "from node2vec import Node2Vec\n",
        "\n",
        "node2vec = Node2Vec(G, dimensions=64, walk_length=20, num_walks=200, p=2, q=1, workers=1)\n",
        "\n",
        "model = node2vec.fit(window=10, min_count=1, batch_words=4)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "ImKP41Ybrnhw"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Return of the Jedi (1983): 0.61\n",
            "Raiders of the Lost Ark (1981): 0.55\n",
            "Godfather, The (1972): 0.49\n",
            "Indiana Jones and the Last Crusade (1989): 0.46\n",
            "White Squall (1996): 0.44\n"
          ]
        }
      ],
      "source": [
        "def recommend(movie):\n",
        "    movie_id = str(movies[movies.title == movie].movie_id.values[0])\n",
        "    for id in model.wv.most_similar(movie_id)[:5]:\n",
        "        title = movies[movies.movie_id == int(id[0])].title.values[0]\n",
        "        print(f'{title}: {id[1]:.2f}')\n",
        "\n",
        "recommend('Star Wars (1977)')"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "book",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.15"
    },
    "vscode": {
      "interpreter": {
        "hash": "3556630122da5213751af4465d61fcf5a52cd22515d400aee51118aaa1721248"
      }
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "0214cb6383934ef1856188a9cad2b1f5": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_bd7eec057b9b463b8ec4a73124d44a90",
            "placeholder": "​",
            "style": "IPY_MODEL_baf82e035dc745b7bacf4faca185daf1",
            "value": " 643/643 [01:35&lt;00:00, 45.27it/s]"
          }
        },
        "1b84f3c6fa9c4599a59e765f1dda64bc": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "69a57be4fda84d3aad2c0ecdced02f26": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "7cfb833108bb4948bd900d8ea79f6ea7": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_955ac231d4124300bc2c03097a39a256",
            "placeholder": "​",
            "style": "IPY_MODEL_69a57be4fda84d3aad2c0ecdced02f26",
            "value": "Computing transition probabilities: 100%"
          }
        },
        "90e8a5c45e93473d8566096dcda21b00": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "FloatProgressModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_1b84f3c6fa9c4599a59e765f1dda64bc",
            "max": 643,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_a2e964b1261743deb4e21d847a85b3bb",
            "value": 643
          }
        },
        "955ac231d4124300bc2c03097a39a256": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "a2e964b1261743deb4e21d847a85b3bb": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "ProgressStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "baf82e035dc745b7bacf4faca185daf1": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "bd7eec057b9b463b8ec4a73124d44a90": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "e24e7b63096849fc8b290745429a103c": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "eeb0f16e73a44771a4cd98b296a2f504": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HBoxModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_7cfb833108bb4948bd900d8ea79f6ea7",
              "IPY_MODEL_90e8a5c45e93473d8566096dcda21b00",
              "IPY_MODEL_0214cb6383934ef1856188a9cad2b1f5"
            ],
            "layout": "IPY_MODEL_e24e7b63096849fc8b290745429a103c"
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
